1 00:00:00,170 --> 00:00:04,970 In this lecture, we're going to be taking a look at memory stores. 2 00:00:04,970 --> 00:00:11,150 Memory stores are very similar to data stores, but they allow you to have higher throughput and low 3 00:00:11,150 --> 00:00:12,830 latency data storage. 4 00:00:12,830 --> 00:00:17,330 That also allows you to share and store data between multiple servers very quickly. 5 00:00:17,330 --> 00:00:23,750 Memory stores have a much higher API request limit, which is also dependent on how many players are 6 00:00:23,750 --> 00:00:24,410 in your game. 7 00:00:24,410 --> 00:00:30,650 So memory stores are a great and flexible option when you need to constantly update data very quickly, 8 00:00:30,650 --> 00:00:33,770 but also share that data between multiple servers. 9 00:00:34,040 --> 00:00:38,930 If we take a look at the Roblox documentation, it states that the Memory Stores service is a high throughput 10 00:00:38,930 --> 00:00:44,570 and low latency data service that provides fast, in-memory data storage accessible from all servers 11 00:00:44,570 --> 00:00:45,950 in a live session. 12 00:00:45,950 --> 00:00:51,440 Memory stores are suitable for frequent and ephemeral data that can change rapidly and don't need to 13 00:00:51,440 --> 00:00:56,450 be durable because they are faster to access and vanish when reaching the maximum lifetime. 14 00:00:56,450 --> 00:01:02,060 For data that needs to be persistent and static across sessions, you should use data stores. 15 00:01:02,180 --> 00:01:05,240 They give us some examples of what we could use memory stores for. 16 00:01:05,240 --> 00:01:08,090 For example, you could use it for skill based matchmaking. 17 00:01:08,090 --> 00:01:13,250 Save user information such as skill level and a shared queue among servers, and use lobby servers to 18 00:01:13,250 --> 00:01:15,050 run matchmaking periodically. 19 00:01:15,050 --> 00:01:17,630 You can use it for cross server trading and auctioning. 20 00:01:17,630 --> 00:01:22,730 Enable universal trading between different servers on items where users can bid on items with real time 21 00:01:22,730 --> 00:01:26,360 changing prices stored inside a map as key value pairs. 22 00:01:26,360 --> 00:01:31,670 Global leaderboards store and update user rankings on a shared leaderboard inside a map with key value 23 00:01:31,670 --> 00:01:32,210 pairs. 24 00:01:32,210 --> 00:01:38,240 Cache for persistent data sync and copy your persistent data in a data store to a memory store. 25 00:01:38,240 --> 00:01:44,540 Map with key value pairs to function as caches, which can help improve your experiences performance. 26 00:01:44,960 --> 00:01:48,740 So there are basically two structures in memory stores. 27 00:01:48,740 --> 00:01:54,740 You can have a queue, which is basically an array, and you can have a map which acts as a dictionary. 28 00:01:54,740 --> 00:01:59,570 So one is based on index value pairs, while the other is based on key value pairs. 29 00:01:59,570 --> 00:02:04,760 Your sorted maps are going to be for your dictionary based application, and your keys are going to 30 00:02:04,760 --> 00:02:07,220 be for your array based applications. 31 00:02:07,220 --> 00:02:13,490 As an example, with memory stores, a project that I'm working on, I'm using memory stores to store 32 00:02:13,490 --> 00:02:16,940 information about private servers that are being hosted somewhere. 33 00:02:16,940 --> 00:02:18,800 You can think of them as like a session. 34 00:02:18,800 --> 00:02:24,650 And if some kind of player accidentally disconnects from that private server and then rejoins the game, 35 00:02:24,650 --> 00:02:30,230 the server can check to see if they were inside of a previous session, and it will prompt them to rejoin 36 00:02:30,230 --> 00:02:32,450 that session because they disconnected. 37 00:02:32,450 --> 00:02:38,030 If the private server closes, then that session information is removed from the memory store and the 38 00:02:38,030 --> 00:02:39,950 server won't check for that particular player. 39 00:02:39,950 --> 00:02:45,410 Now, since game sessions are going to be short lived and lots can be created quickly, it makes the 40 00:02:45,410 --> 00:02:48,740 most sense to me to store them inside of a memory store. 41 00:02:49,190 --> 00:02:55,220 Now, of course, just like data stores, memory stores also have API request limits and a data structure 42 00:02:55,220 --> 00:02:55,940 size limits. 43 00:02:55,940 --> 00:02:59,930 Of course, these limits are much higher than data stores because you're going to be using these very 44 00:02:59,930 --> 00:03:00,410 quickly. 45 00:03:00,410 --> 00:03:02,780 But let's go ahead and take a look at the limits real quick. 46 00:03:02,780 --> 00:03:09,920 It says for API request limits there's a request unit quota applying to all API calls, which is 1000 47 00:03:09,920 --> 00:03:14,270 plus 100 times the number of concurrent users request units per minute. 48 00:03:14,270 --> 00:03:21,080 Additionally, the rate of requests to any single queue or sorted map is limited to 100,000 request 49 00:03:21,080 --> 00:03:22,700 units per minute. 50 00:03:22,700 --> 00:03:29,720 Most API calls only consume one request unit, with the exceptions of the JIT range, async function 51 00:03:29,720 --> 00:03:32,810 for sorted maps, and the read async function for queues. 52 00:03:32,810 --> 00:03:38,360 These two methods consume units based on the number of returned items with at least one request unit. 53 00:03:38,360 --> 00:03:43,640 For example, if the JIT range async function returned ten items, the total quota counts based on a 54 00:03:43,640 --> 00:03:45,140 ten request units. 55 00:03:45,140 --> 00:03:50,030 If it returns an empty response without items, the quota counts based on a single request unit and 56 00:03:50,030 --> 00:03:50,450 then read. 57 00:03:50,450 --> 00:03:53,900 Async consumes an additional unit every two seconds while reading. 58 00:03:53,900 --> 00:03:56,900 The maximum read time is specified using the wait timeout parameter. 59 00:03:56,900 --> 00:04:01,490 A bunch of technical details, but as long as you set up your memory stores correctly, you shouldn't 60 00:04:01,490 --> 00:04:03,800 have to worry about hitting these different limits. 61 00:04:04,220 --> 00:04:11,330 When it comes to a sorted map or a queue in a memory store, there is a following size and item count 62 00:04:11,330 --> 00:04:18,320 limit, so you can have a maximum number of 1000 keys or indexes, and then you can have a maximum total 63 00:04:18,320 --> 00:04:22,160 size of 100 megabyte per sorted map or queue. 64 00:04:22,160 --> 00:04:28,310 So if you think you're going to exceed this 100 megabyte or this 1000 number limit, then you might 65 00:04:28,310 --> 00:04:34,280 want to split your code or your memory store up into multiple different sorted maps or multiple different 66 00:04:34,280 --> 00:04:35,030 queues. 67 00:04:35,390 --> 00:04:41,390 This article also talks about some best practices when you're using memory stores to avoid hitting the 68 00:04:41,390 --> 00:04:43,460 limits, and a bunch of other information. 69 00:04:43,460 --> 00:04:48,230 This article will be linked in this lecture for you to go ahead and read through it if you'd like to 70 00:04:48,230 --> 00:04:49,340 learn more information. 71 00:04:49,340 --> 00:04:51,020 But enough talking about this. 72 00:04:51,020 --> 00:04:56,510 Let's actually go ahead and go to the Memory Store documentation page so we can take a look at all of 73 00:04:56,510 --> 00:04:58,160 the different API functions. 74 00:04:58,950 --> 00:05:02,610 So right now the memory store service has two working functions. 75 00:05:02,610 --> 00:05:05,760 One is git queue and the other one is git sorted map. 76 00:05:05,760 --> 00:05:11,220 So one of them returns an array or a memory store queue, and the other returns a memory sorted map. 77 00:05:11,220 --> 00:05:13,530 There's this other function here called git hash map. 78 00:05:13,530 --> 00:05:17,430 This is not currently working as the recording of this lecture I tried. 79 00:05:17,430 --> 00:05:18,420 It doesn't do anything. 80 00:05:18,420 --> 00:05:19,800 It actually spits out an error. 81 00:05:19,800 --> 00:05:23,880 So this seems to be an incomplete feature that you cannot use at the moment. 82 00:05:23,880 --> 00:05:27,030 So we're just going to be focusing on these two functions. 83 00:05:27,480 --> 00:05:31,170 So the git queue function returns a memory store queue instance. 84 00:05:31,170 --> 00:05:34,350 And the git sorted map returns a memory store sorted map instance. 85 00:05:34,350 --> 00:05:37,200 Let's go ahead and first take a look at memory store queue. 86 00:05:37,750 --> 00:05:39,010 And it says Memorystore. 87 00:05:39,010 --> 00:05:41,920 Q provides access to a queue within Memorystore. 88 00:05:41,950 --> 00:05:47,230 A queue is a data structure that provides temporary storage for arbitrary items, and as you can see, 89 00:05:47,230 --> 00:05:48,850 it has a few functions. 90 00:05:48,850 --> 00:05:52,810 One is to add a value into the queue. 91 00:05:52,840 --> 00:06:00,100 One is to read a certain number of values from the queue, and then once to remove items from the queue 92 00:06:00,100 --> 00:06:01,390 based on an ID. 93 00:06:01,510 --> 00:06:06,940 So when you read items from the queue, you'll get a count which will be the number of items in the 94 00:06:06,940 --> 00:06:07,990 queue that you want to read. 95 00:06:07,990 --> 00:06:13,270 Let's say it's five items and then this will return um, some different values. 96 00:06:13,270 --> 00:06:18,910 So if we actually head down to the documentation it says it returns, uh, two elements. 97 00:06:18,910 --> 00:06:22,660 The first element is array of item values that were stored in the queue. 98 00:06:22,660 --> 00:06:25,390 And then the second element is a string identifier. 99 00:06:25,390 --> 00:06:32,650 And this is the string identifier that you would use for the remove async function to remove certain 100 00:06:32,650 --> 00:06:34,570 values from your memorystore. 101 00:06:34,570 --> 00:06:40,240 Because, for example, once you read certain values and do something with it, you'll likely want to 102 00:06:40,240 --> 00:06:42,730 discard those values and not use them anymore. 103 00:06:42,730 --> 00:06:48,880 So that's why this function returns a string ID, which you can use in the remove async function to 104 00:06:48,880 --> 00:06:51,340 remove those values from the queue. 105 00:06:51,340 --> 00:06:57,400 Now, something also interesting to note is that when you add items or values into your memorystore 106 00:06:57,400 --> 00:07:03,490 queue, you can also give it an optional priority and it says items with higher priority are retrieved 107 00:07:03,490 --> 00:07:06,130 from the queue before items with a lower priority. 108 00:07:06,130 --> 00:07:11,500 So if there is particular values you want to store inside of this array that you want to receive first 109 00:07:11,500 --> 00:07:15,070 before other items, you can set them to have a higher priority. 110 00:07:15,070 --> 00:07:21,040 You are also able to control the expiration date for a particular value inside of your memory store. 111 00:07:21,040 --> 00:07:26,470 Because memory stores are not permanent storages of values, they will expire. 112 00:07:26,470 --> 00:07:30,280 The default expiration, I believe, is 45 days. 113 00:07:30,280 --> 00:07:34,390 But sometimes you don't need to store values in your memory store for 45 days. 114 00:07:34,390 --> 00:07:39,190 Maybe you only need to store it for like an hour or less, so you can define how long you want the expiration 115 00:07:39,190 --> 00:07:42,580 to be in seconds with this other optional parameter. 116 00:07:42,580 --> 00:07:44,320 Okay, that's enough of me talking. 117 00:07:44,320 --> 00:07:47,350 Let's actually go ahead and see memory stores in action. 118 00:07:47,350 --> 00:07:51,370 Let's go ahead and make a variable for the memory store service. 119 00:07:51,370 --> 00:07:54,760 So we'll do game and get service memory store service. 120 00:07:57,150 --> 00:08:00,330 And then let's go ahead and get a memorystore queue. 121 00:08:00,360 --> 00:08:01,350 I'll create my variable. 122 00:08:01,350 --> 00:08:02,400 I'll just call it queue. 123 00:08:02,400 --> 00:08:04,770 And this is going to be equal to the Memorystore service. 124 00:08:04,770 --> 00:08:06,180 Get queue. 125 00:08:06,330 --> 00:08:08,760 And we want to give a name for this queue. 126 00:08:08,760 --> 00:08:13,260 And this name will be universal across multiple different places in your experience. 127 00:08:13,260 --> 00:08:17,250 So that way all your places can access the same memorystore queue. 128 00:08:17,280 --> 00:08:21,960 I'll just call this my example queue, but you can name it whatever you want. 129 00:08:21,960 --> 00:08:25,830 Just make sure it's a good name for whatever you're going to be using this memorystore for. 130 00:08:26,550 --> 00:08:32,970 And then there's an optional parameter here called invisibility timeout and it says returns a memorystore 131 00:08:32,970 --> 00:08:34,860 queue instance private for that name. 132 00:08:34,860 --> 00:08:41,190 And then this timeout says invisibility timeout in seconds for read operations through this queue instance. 133 00:08:41,190 --> 00:08:44,700 If not provided, defaults to 30s. 134 00:08:45,500 --> 00:08:47,870 If we take a look at the documentation. 135 00:08:47,870 --> 00:08:52,550 As you can see, we have the exact same description for this invisibility timeout. 136 00:08:52,550 --> 00:08:56,300 And it's not exactly clear what this means, but I'll break it down for you. 137 00:08:56,330 --> 00:09:02,870 Basically, when you use different read functions like the read async function for a memorystore queue, 138 00:09:02,900 --> 00:09:08,570 you want to basically be able to hide or make the values that you're reading invisible from the queue. 139 00:09:08,570 --> 00:09:14,270 So that way other servers or other, let's say other functions, don't read these values at the same 140 00:09:14,270 --> 00:09:15,080 time. 141 00:09:15,080 --> 00:09:17,150 Another function is reading these values. 142 00:09:17,150 --> 00:09:24,050 So it hides basically those values from being read when you're currently reading it through an operation. 143 00:09:24,050 --> 00:09:26,300 And the default is 30s. 144 00:09:26,300 --> 00:09:28,220 So yeah, just leave this at 30. 145 00:09:28,220 --> 00:09:30,650 You're not going to have to worry about this that much. 146 00:09:31,070 --> 00:09:34,220 So let's go ahead and leave this at the default value of 30s. 147 00:09:34,220 --> 00:09:36,170 And let's just go ahead and get our queue. 148 00:09:36,170 --> 00:09:41,360 Now what I want to do is I want to get my player service. 149 00:09:41,360 --> 00:09:47,180 So let's actually grab that player's is equal to game get service players. 150 00:09:47,660 --> 00:09:52,730 And then let's go ahead and listen for when a player is added to the game we'll get that player. 151 00:09:55,730 --> 00:09:58,700 And then let's go ahead and listen for when this player chats. 152 00:09:58,970 --> 00:10:04,700 Because what I want to do is for demonstration purposes, I want to store the message that they send 153 00:10:04,700 --> 00:10:07,280 in the chat inside of my memory store. 154 00:10:07,760 --> 00:10:14,840 So the easiest way to do this is we can refer to our queue and we can add an item into it using the 155 00:10:14,840 --> 00:10:16,940 add async function. 156 00:10:16,940 --> 00:10:20,690 The value we want to add is, well, just their string message. 157 00:10:20,690 --> 00:10:23,960 So we can just pass the message here for the expiration date. 158 00:10:23,960 --> 00:10:27,680 We don't need to store this value that long in the data store. 159 00:10:27,680 --> 00:10:29,630 Definitely not 45 days. 160 00:10:29,630 --> 00:10:32,390 So let's just set it to a value of like 100 seconds. 161 00:10:32,390 --> 00:10:36,980 After 100 seconds, this value will automatically be removed from our memory store. 162 00:10:37,370 --> 00:10:40,580 Now the last value here is going to be a optional priority. 163 00:10:40,580 --> 00:10:45,410 And it says items with higher priority are retrieved from the queue before items with a lower priority. 164 00:10:45,410 --> 00:10:51,290 And I basically want to have the ability, when I'm reading values from this queue to get all of the 165 00:10:51,290 --> 00:10:53,990 messages that are longer first. 166 00:10:53,990 --> 00:11:00,740 So the easy way to do that is to set the priority equal to the length of the message, so longer messages 167 00:11:00,740 --> 00:11:02,360 have a higher priority. 168 00:11:02,880 --> 00:11:08,400 Now, since this is an asynchronous function, there is the opportunity or a chance that this function 169 00:11:08,400 --> 00:11:10,980 could error and your code could stop working. 170 00:11:10,980 --> 00:11:16,620 So just in case, let's go ahead and wrap this in a p call so we can do success. 171 00:11:16,620 --> 00:11:18,360 Error is equal to p call. 172 00:11:18,870 --> 00:11:21,750 And then we can just copy this and place it in there. 173 00:11:21,750 --> 00:11:26,310 And if for some reason we were not successful in storing this value inside of our memorystore queue, 174 00:11:26,340 --> 00:11:29,100 we can just warn and spit out that error message. 175 00:11:29,520 --> 00:11:34,920 Now to begin actually reading values from this memorystore queue, we're going to need to have a while 176 00:11:34,920 --> 00:11:36,870 loop that basically just runs forever. 177 00:11:36,870 --> 00:11:40,350 We can have it run every maybe one second or 10s. 178 00:11:40,350 --> 00:11:43,920 Let's do 10s to read information from the Memorystore. 179 00:11:43,920 --> 00:11:50,100 And that's because there isn't any events that you can listen to for when a value is added into a queue, 180 00:11:50,130 --> 00:11:54,600 you're just going to have to actively pull and grab data from your memorystore. 181 00:11:55,110 --> 00:12:00,180 So what we're going to go ahead and do here is we're going to use the function inside of our memorystore 182 00:12:00,180 --> 00:12:00,720 queue. 183 00:12:00,750 --> 00:12:03,180 That is going to be the read async function. 184 00:12:03,180 --> 00:12:06,870 We can give it the number of items that we want to read from the queue. 185 00:12:06,870 --> 00:12:13,200 So let's go ahead and just grab let's say the first five messages from the queue. 186 00:12:13,200 --> 00:12:16,170 Now there's this other optional parameter called all or nothing. 187 00:12:16,170 --> 00:12:19,200 And it says controls the behavior of the method. 188 00:12:19,200 --> 00:12:23,070 In the case the queue has fewer than count items. 189 00:12:23,070 --> 00:12:26,160 If set to false, the method returns all available items. 190 00:12:26,160 --> 00:12:28,800 If set to true, it returns no items. 191 00:12:28,800 --> 00:12:30,120 The default is false. 192 00:12:30,120 --> 00:12:34,470 So for example, let's say there's three items in the queue, but we want to grab five. 193 00:12:34,470 --> 00:12:37,980 If we set it to false, it's just going to return to us those three values. 194 00:12:37,980 --> 00:12:44,190 But if we set it to true then it's going to return nothing because we want five values, but our queue 195 00:12:44,190 --> 00:12:46,170 only has three values inside of it. 196 00:12:46,170 --> 00:12:48,510 We're just going to leave this at the default of false. 197 00:12:49,590 --> 00:12:52,800 And then this last optional parameter is called wait timeout. 198 00:12:52,800 --> 00:12:56,730 And it says the duration in seconds for which the method will wait. 199 00:12:56,730 --> 00:13:00,570 If the required number of items is not immediately available in the queue. 200 00:13:00,600 --> 00:13:03,630 Reads are attempted every two seconds during this period. 201 00:13:03,660 --> 00:13:06,480 This parameter can be set to zero to indicate no wait. 202 00:13:06,480 --> 00:13:10,920 If this parameter is not provided or set to negative one, the method will wait indefinitely. 203 00:13:11,220 --> 00:13:15,150 So let's say we want to grab five items, but our queue has only one item. 204 00:13:15,150 --> 00:13:21,360 We could specify a wait timeout of how long we want to wait before we get those five items to show up, 205 00:13:21,360 --> 00:13:27,090 or if we just leave it at the default, then this function right here is going to wait and yield until 206 00:13:27,090 --> 00:13:28,980 we get those five items. 207 00:13:29,310 --> 00:13:34,020 Since these are both optional parameters, I'm actually just going to leave them both at the default, 208 00:13:34,020 --> 00:13:39,330 and we're just going to grab the first five items inside of our queue. 209 00:13:39,360 --> 00:13:44,700 Now, since this is also an asynchronous function, we need to wrap it inside of a p call so we can 210 00:13:44,700 --> 00:13:45,750 do success. 211 00:13:45,990 --> 00:13:50,250 Uh, result is equal to p call. 212 00:13:50,250 --> 00:13:55,140 Wrap that in a function, put that in there and we want to return the result from our function. 213 00:13:55,140 --> 00:13:58,890 And this result should be a table containing all of our items. 214 00:13:58,890 --> 00:14:04,710 So we could actually rename this to items if we were not successful in grabbing the items. 215 00:14:04,710 --> 00:14:08,250 If there was some kind of error, then we can just spin out the warning for the error message which 216 00:14:08,250 --> 00:14:10,170 will be stored in our items variable. 217 00:14:10,500 --> 00:14:16,410 Otherwise, what we can go ahead and do is we can check if the number of items we received is greater 218 00:14:16,410 --> 00:14:17,130 than zero. 219 00:14:17,130 --> 00:14:18,720 So at least we got something. 220 00:14:18,720 --> 00:14:23,010 So if the length of our table is greater than zero, then let's just go ahead and print out all those 221 00:14:23,010 --> 00:14:23,760 items we got. 222 00:14:23,760 --> 00:14:30,810 We could say this is from our queue and we'll print out these are the items that we got. 223 00:14:33,010 --> 00:14:37,420 And then after we're done messing with these values, for example, maybe we need to do other stuff 224 00:14:37,420 --> 00:14:37,720 with it. 225 00:14:37,720 --> 00:14:39,280 I'm just going to print it out for now. 226 00:14:39,280 --> 00:14:44,440 Once we're done with these items, we should probably remove them from the queue because we don't want 227 00:14:44,440 --> 00:14:46,060 to read them again in the future. 228 00:14:46,060 --> 00:14:51,880 So this is where we need to refer to our queue and use the remove async function. 229 00:14:52,510 --> 00:14:54,670 So let's also wrap that in a p call. 230 00:14:54,670 --> 00:15:01,150 We could do success and then uh get the error message that's going to be equal to p call function. 231 00:15:01,270 --> 00:15:06,820 We refer to our queue and we want to remove these values from our queue. 232 00:15:06,820 --> 00:15:09,580 But remember we need to pass an ID here. 233 00:15:09,580 --> 00:15:11,620 Wait where do we get the ID from. 234 00:15:11,620 --> 00:15:17,170 Well thankfully the read async function, if you remember, returns the id so we can create one more 235 00:15:17,170 --> 00:15:17,950 variable here. 236 00:15:17,950 --> 00:15:19,660 We'll call this our id. 237 00:15:19,750 --> 00:15:23,530 And this is the ID for those particular values that we got. 238 00:15:23,530 --> 00:15:30,550 And then we can pass that ID to our remove async function to remove them from our memorystore queue. 239 00:15:30,910 --> 00:15:35,020 And then of course if we were not successful in doing that, we'll just spit out whatever that error 240 00:15:35,020 --> 00:15:36,790 message is into the console. 241 00:15:37,240 --> 00:15:37,750 Okay. 242 00:15:37,750 --> 00:15:41,830 We should basically have everything coded and set up for our Memorystore queue. 243 00:15:41,830 --> 00:15:44,890 Let's go ahead and test it out by playtesting the game. 244 00:15:44,890 --> 00:15:47,590 Make sure your game is published if you want to test this out. 245 00:15:47,590 --> 00:15:52,570 And then you also have to make sure inside of your game settings that you have enable Studio Access 246 00:15:52,570 --> 00:15:55,270 to API services enabled, or else this won't work. 247 00:15:55,270 --> 00:15:58,630 But I already have all of that enabled, so I'm going to play test my game. 248 00:16:00,580 --> 00:16:03,460 And then I can type out some messages like hello? 249 00:16:03,490 --> 00:16:07,690 I can type out howdy, and I could type out hi. 250 00:16:07,810 --> 00:16:12,340 And then as you can see after 10s we got some values from our queue. 251 00:16:12,340 --> 00:16:14,740 And if we take a look as you see we got hello. 252 00:16:14,770 --> 00:16:15,580 We got howdy. 253 00:16:15,580 --> 00:16:17,260 And we also got hi. 254 00:16:17,290 --> 00:16:18,940 Those are the three messages we got. 255 00:16:18,940 --> 00:16:24,370 And if you notice the messages that are longer are at the beginning of the queue and the smaller message 256 00:16:24,370 --> 00:16:25,480 is at the end of the queue. 257 00:16:25,480 --> 00:16:28,450 And this is true for all sorts of different messages. 258 00:16:28,450 --> 00:16:33,790 So if I say hello there and then I say hello and then I say oops, looks like the queue already happened. 259 00:16:33,820 --> 00:16:35,020 Let me go ahead and take a look at that. 260 00:16:35,020 --> 00:16:35,650 There we go. 261 00:16:35,650 --> 00:16:36,100 Hello. 262 00:16:36,100 --> 00:16:41,650 There is first because it's the longer string and hello is second because it's the shorter string. 263 00:16:41,650 --> 00:16:47,200 And that's because we're using that priority value when we're storing stuff in our queue. 264 00:16:47,230 --> 00:16:54,070 Now, if I were to get rid of this priority and just store stuff in my memorystore queue, then when 265 00:16:54,070 --> 00:16:59,140 we read the items inside of it, it's probably just going to be based on when those different messages 266 00:16:59,140 --> 00:17:00,520 were added into the queue. 267 00:17:01,120 --> 00:17:08,740 So if I send a small message like hi, then hello, and then hi there, we should get a table containing 268 00:17:08,740 --> 00:17:10,600 the messages in that order. 269 00:17:10,600 --> 00:17:11,500 And there we go. 270 00:17:11,500 --> 00:17:12,040 Hi. 271 00:17:12,040 --> 00:17:13,390 Hello and hi there. 272 00:17:13,390 --> 00:17:18,340 So it's in the same order that we sent them out inside of the chat. 273 00:17:18,340 --> 00:17:19,420 Let's go ahead and do that again. 274 00:17:19,420 --> 00:17:21,190 We could do hello. 275 00:17:21,190 --> 00:17:23,650 We could do hi and we could do was up. 276 00:17:23,860 --> 00:17:24,190 Oops. 277 00:17:24,190 --> 00:17:25,630 Looks like the queue already printed. 278 00:17:25,630 --> 00:17:25,960 Okay. 279 00:17:25,960 --> 00:17:26,200 We got. 280 00:17:26,200 --> 00:17:26,500 Hello. 281 00:17:26,500 --> 00:17:27,040 Hi. 282 00:17:27,040 --> 00:17:28,300 Let's try that again. 283 00:17:28,300 --> 00:17:29,260 Let's do. 284 00:17:29,260 --> 00:17:33,520 Um, actually, you know what WhatsApp should print in the next queue? 285 00:17:33,520 --> 00:17:34,330 Let's see. 286 00:17:34,450 --> 00:17:34,840 Okay. 287 00:17:34,840 --> 00:17:35,080 Yeah. 288 00:17:35,080 --> 00:17:35,650 There we go. 289 00:17:35,650 --> 00:17:36,400 There it is. 290 00:17:36,400 --> 00:17:40,300 Because WhatsApp was sent after this queue printed. 291 00:17:40,300 --> 00:17:45,490 We got our first two messages, but our WhatsApp was still inside of the queue, so it wasn't going 292 00:17:45,490 --> 00:17:50,800 to be handled and cleaned up until the next iteration of that loop, which is every 10s. 293 00:17:51,560 --> 00:17:53,660 So that is memory store. 294 00:17:53,660 --> 00:17:59,360 Cuz let's go ahead and take a look at the next data type which is going to be memory store maps. 295 00:17:59,360 --> 00:18:04,850 So let's go ahead and just I'm just going to delete all of this code because I don't need it anymore. 296 00:18:04,880 --> 00:18:05,690 We'll just delete that. 297 00:18:05,690 --> 00:18:06,740 We'll delete that. 298 00:18:07,310 --> 00:18:12,320 And now let's go ahead and make a variable for our sorted map from our memory store. 299 00:18:12,320 --> 00:18:14,180 So I'll just call this sorted. 300 00:18:14,180 --> 00:18:16,340 That's going to be equal to the memory store service. 301 00:18:16,340 --> 00:18:18,410 And we want to go ahead and get a sorted map. 302 00:18:18,410 --> 00:18:23,030 And we got to give it a name I'll just call this my uh example map. 303 00:18:23,560 --> 00:18:27,100 Now of course, our map has some additional functions inside of it. 304 00:18:27,100 --> 00:18:30,970 For example, we can set a value to a particular key. 305 00:18:31,210 --> 00:18:36,340 We can remove a value and a particular key from the sorted map. 306 00:18:36,340 --> 00:18:40,210 We can um, I believe there's a function as well called. 307 00:18:40,210 --> 00:18:40,390 Yep. 308 00:18:40,390 --> 00:18:45,610 We can update a particular key and change its key and its sort key. 309 00:18:45,610 --> 00:18:51,880 And then we can also I believe we can read what is it called read. 310 00:18:51,880 --> 00:18:57,550 No, no no what what is it get I believe it's get async. 311 00:18:57,550 --> 00:18:58,000 Yeah okay. 312 00:18:58,000 --> 00:18:58,450 There we go. 313 00:18:58,450 --> 00:19:02,320 Get async or get sorted. 314 00:19:02,680 --> 00:19:03,100 Dang. 315 00:19:03,100 --> 00:19:04,360 What is it called? 316 00:19:04,360 --> 00:19:05,200 Get okay. 317 00:19:05,200 --> 00:19:06,310 It's called get range. 318 00:19:06,310 --> 00:19:08,860 Yeah that's right get range async. 319 00:19:08,860 --> 00:19:11,560 And you can receive a range of item in the map. 320 00:19:11,560 --> 00:19:15,190 So this is quite similar to memory stores. 321 00:19:15,820 --> 00:19:17,500 But let's go ahead and demonstrate this here. 322 00:19:17,500 --> 00:19:26,260 What I want to do is when the player sends a message I want to store it inside of our map at some kind 323 00:19:26,260 --> 00:19:27,160 of random key. 324 00:19:27,160 --> 00:19:34,090 It doesn't really matter what key it is, but let's go ahead and first make a P call because again these 325 00:19:34,090 --> 00:19:35,200 are async functions. 326 00:19:35,200 --> 00:19:36,190 They can error. 327 00:19:36,430 --> 00:19:37,960 So let's refer to our sorted map. 328 00:19:37,960 --> 00:19:43,540 And let's use the set async function to set a value in a particular key. 329 00:19:43,990 --> 00:19:46,210 Now this key can be whatever you want. 330 00:19:46,210 --> 00:19:51,130 If you need to basically have the same key to be used across multiple different places, you might want 331 00:19:51,130 --> 00:19:52,270 to standardize this. 332 00:19:52,270 --> 00:19:54,940 Maybe you want to use like user IDs of the player. 333 00:19:54,940 --> 00:19:59,440 I'm not really concerned about keys right now, so I'm just going to do like Math.random to generate 334 00:19:59,440 --> 00:20:00,520 a random key. 335 00:20:00,520 --> 00:20:03,940 And the value we want to store here is just going to be the message as well. 336 00:20:04,480 --> 00:20:06,280 We can set a custom expiration date. 337 00:20:06,280 --> 00:20:09,220 I'm also going to do 100 seconds. 338 00:20:09,790 --> 00:20:13,930 And then we are able to give it an optional sort key. 339 00:20:13,930 --> 00:20:20,620 So this is very very similar to the priority value that was in the memorystore queue. 340 00:20:20,650 --> 00:20:28,210 This basically allows us to grab or sort items inside of this um dictionary by using the sort key, 341 00:20:28,210 --> 00:20:30,130 but it's a little bit different. 342 00:20:30,130 --> 00:20:37,300 The smaller the value of the sort key, the higher priority a value will be when we're sorting it. 343 00:20:37,300 --> 00:20:43,880 So basically, if the value is like negative one, that is a higher sort priority than a value of 0 344 00:20:43,880 --> 00:20:44,560 or 1. 345 00:20:44,560 --> 00:20:46,720 So this goes in the other direction. 346 00:20:46,720 --> 00:20:48,160 It's actually negative. 347 00:20:48,160 --> 00:20:49,990 That gets higher priority. 348 00:20:49,990 --> 00:20:56,380 But for the sort key we're just going to do the exact same thing that we did with our queue. 349 00:20:56,410 --> 00:20:59,350 We're going to set it equal to the length of the message. 350 00:20:59,680 --> 00:21:04,750 Now we can go ahead and check to see if this P call was successful and if we got an error message from 351 00:21:04,750 --> 00:21:05,020 it. 352 00:21:05,020 --> 00:21:11,470 So that way if we were not successful, then we can just spit out a warning and say something like or 353 00:21:11,470 --> 00:21:13,990 no, we'll just we'll just spit out the error message. 354 00:21:14,770 --> 00:21:22,030 Now the other function I actually want to demonstrate with the sorted Memorystore map is the update 355 00:21:22,030 --> 00:21:22,930 async function. 356 00:21:22,930 --> 00:21:28,090 So what I'm going to do is I'm going to check if this message the player send is equal to a string of 357 00:21:28,090 --> 00:21:30,700 like um, let's specify something specific here. 358 00:21:30,700 --> 00:21:32,500 We could do exclamation mark update. 359 00:21:32,590 --> 00:21:34,210 This is how I'll demonstrate it. 360 00:21:34,660 --> 00:21:40,030 If it's equal to this message, then we'll do something with the update async function. 361 00:21:40,030 --> 00:21:43,570 Otherwise we'll just save that message inside of our sorted map. 362 00:21:44,660 --> 00:21:51,650 But what we'll do here is that if the player says exclamation mark update, let's go ahead and use the 363 00:21:51,650 --> 00:21:53,330 update async function. 364 00:21:53,930 --> 00:22:01,190 And the key is going to be, um, oh wait, we need to standardize a key here because we're not going 365 00:22:01,190 --> 00:22:03,620 to know what Math.random is. 366 00:22:03,620 --> 00:22:08,990 So let's actually add, uh, another like special message. 367 00:22:08,990 --> 00:22:17,360 So if the message is equal to let's say uh save, then let's go ahead and save a key value pair inside 368 00:22:17,360 --> 00:22:19,070 of our map. 369 00:22:19,070 --> 00:22:23,300 That's going to be using the player's user ID as the key. 370 00:22:23,300 --> 00:22:27,020 So we can do actually let me just copy this. 371 00:22:27,020 --> 00:22:36,230 What we'll do here is we'll use the user ID of this player and the value will store here is um, we 372 00:22:36,230 --> 00:22:38,000 could actually just do the exact same thing here. 373 00:22:38,210 --> 00:22:39,440 We'll just paste that here. 374 00:22:39,440 --> 00:22:43,550 We'll store the message which should be this and give it the same priority. 375 00:22:43,550 --> 00:22:47,390 It doesn't really matter, but we'll put that inside of the memory store. 376 00:22:47,390 --> 00:22:52,460 And of course, if that's not successful, we'll warn and say what the error is in the console. 377 00:22:52,520 --> 00:22:58,940 But now, since we should be able to save this data for this player's user ID, that means we can update 378 00:22:58,940 --> 00:23:00,950 it based on their user ID. 379 00:23:00,950 --> 00:23:02,990 So we'll pass the user ID of the player here. 380 00:23:02,990 --> 00:23:05,600 And then we need to give it a transform function. 381 00:23:05,600 --> 00:23:10,820 So this is very similar to the update async function that you may see inside of uh data stores. 382 00:23:10,820 --> 00:23:16,850 And this function is going to be passed the value that is stored at this key. 383 00:23:16,850 --> 00:23:21,140 And then it's also going to pass the sort key if it exists. 384 00:23:21,140 --> 00:23:28,250 So what we'll do here is I'll just print out what the previous value that was stored in here was. 385 00:23:28,250 --> 00:23:33,590 So we could do value and then also print out the previous sort key. 386 00:23:34,280 --> 00:23:36,470 We'll print that out into the console. 387 00:23:36,860 --> 00:23:42,980 And then afterwards I need to return the new value and the new sort key that we want to replace at this 388 00:23:42,980 --> 00:23:44,300 particular key. 389 00:23:44,660 --> 00:23:51,170 So um, let's just do some random value like I'll save a new string and we'll just call it something 390 00:23:51,170 --> 00:23:56,270 like new value, and then we'll just put in some kind of random sort key like a value of 100. 391 00:23:56,270 --> 00:23:57,290 Doesn't really matter. 392 00:23:57,290 --> 00:23:57,980 Okay. 393 00:23:57,980 --> 00:24:05,210 Now we have all of the saving logic set up for our, uh, memory store map. 394 00:24:05,330 --> 00:24:07,100 Is there anything else I need to add here? 395 00:24:07,100 --> 00:24:07,580 Oh. 396 00:24:08,210 --> 00:24:08,630 Looks like. 397 00:24:08,630 --> 00:24:14,330 We can also specify the expiration as well for this new value and this new sort key inside of the update 398 00:24:14,330 --> 00:24:15,260 async function. 399 00:24:15,260 --> 00:24:22,550 So let's also make sure to specify that we want it to exist for 100 seconds for the update async function 400 00:24:22,550 --> 00:24:23,240 okay. 401 00:24:23,240 --> 00:24:26,840 Now we can go to our while loop. 402 00:24:26,840 --> 00:24:35,090 And what I want to do here is I want to first get my player, which is um, what I could do is I could 403 00:24:35,090 --> 00:24:37,220 do player is equal to players. 404 00:24:37,220 --> 00:24:41,540 I'll get my players in the game and I'll just grab the first player that is in the game. 405 00:24:42,140 --> 00:24:46,580 Uh, if there is no player, then we'll just continue looping until we get a player. 406 00:24:48,680 --> 00:24:49,700 Otherwise. 407 00:24:49,700 --> 00:24:53,180 This is where we can do the logic for our memory store. 408 00:24:53,180 --> 00:24:58,910 So let's refer to our sorted memory store map and let's use the get range async function. 409 00:24:58,910 --> 00:25:04,430 We have to give it an enum of sort direction, the count, or how many key value pairs we want to look 410 00:25:04,430 --> 00:25:04,550 at. 411 00:25:04,550 --> 00:25:06,740 And then there's some other optional parameters here. 412 00:25:06,980 --> 00:25:14,030 But let's go ahead and do the enum dot sort order of or oops sort direction of. 413 00:25:14,030 --> 00:25:16,220 Let's do it in ascending order. 414 00:25:16,520 --> 00:25:22,130 Let's go ahead and grab the first five elements, just like we did for the queue. 415 00:25:23,290 --> 00:25:29,500 And then these other optional parameters can specify like a limit, a lower bound, and an upper bound 416 00:25:29,500 --> 00:25:35,770 limit, and it says for the exclusive lower bound it says exclusive for the return keys. 417 00:25:35,770 --> 00:25:41,290 This is provided as a table where one or both of key and sort key can be specified. 418 00:25:41,290 --> 00:25:51,790 And this basically allows us to stop getting um, values from our sorted map based on the key and the 419 00:25:51,790 --> 00:25:52,120 string. 420 00:25:52,120 --> 00:25:58,570 So if there's any keys that would be considered less than our exclusive lower bound, we're going to 421 00:25:58,570 --> 00:26:00,010 not get them and ignore them. 422 00:26:00,010 --> 00:26:01,990 And that's going to be the same thing with the sort key. 423 00:26:01,990 --> 00:26:06,520 If there's any sort keys that are considered lower than the lower bound we specify, it's not going 424 00:26:06,520 --> 00:26:07,480 to grab those either. 425 00:26:07,480 --> 00:26:10,090 And we can do that for the upper bound as well. 426 00:26:10,090 --> 00:26:12,100 So what I'm going to do is I'm going to make a variable. 427 00:26:12,100 --> 00:26:13,780 I'm going to call this my lower bound. 428 00:26:13,780 --> 00:26:16,390 And for now we're going to initialize it with no value. 429 00:26:16,390 --> 00:26:20,410 But we are going to pass it to the function. 430 00:26:20,410 --> 00:26:21,730 This is going to be okay. 431 00:26:21,730 --> 00:26:26,860 We can pass nil here because these uh parameters they are optional. 432 00:26:26,860 --> 00:26:30,400 So it's okay if we pass nil here it's not going to error. 433 00:26:31,060 --> 00:26:35,350 And then after we get that range of items, we can do whatever we want with them. 434 00:26:35,350 --> 00:26:40,870 And then we can update this variable here to a table that specifies the lower bound of the key and the 435 00:26:40,870 --> 00:26:41,320 sort key. 436 00:26:41,320 --> 00:26:44,170 So that way we don't accidentally grab the same values again. 437 00:26:44,500 --> 00:26:47,980 So again let's go ahead and make a p call here. 438 00:26:47,980 --> 00:26:49,120 We'll do success. 439 00:26:49,120 --> 00:26:54,970 And then we'll get an array of items returned from our get range async function. 440 00:26:56,000 --> 00:26:57,860 We'll make sure to return that. 441 00:26:57,860 --> 00:27:02,300 This will return a table of the items, just like with our memory queue. 442 00:27:02,540 --> 00:27:07,250 If we were not successful in getting items, we'll just spit out an error message. 443 00:27:08,670 --> 00:27:11,580 Or oops that should be stored in the items variable. 444 00:27:12,060 --> 00:27:19,530 Otherwise, if the number of items we get is greater than zero, then we can go ahead and basically 445 00:27:19,530 --> 00:27:22,080 just print out what is stored inside of the map. 446 00:27:22,080 --> 00:27:25,110 So I'll just print what items we've got in there. 447 00:27:26,430 --> 00:27:34,950 And then as this while loop continues looping, we're eventually going to reach the end of this sorted 448 00:27:34,950 --> 00:27:37,920 map because we're going in ascending order. 449 00:27:37,920 --> 00:27:45,960 So what we can do is we can check if the number of items is less than five, which is less than the 450 00:27:45,960 --> 00:27:47,430 value that we specified here. 451 00:27:47,430 --> 00:27:52,620 When we're getting the range of items, if it's less than five, this means we've basically reached 452 00:27:52,620 --> 00:27:55,380 the end of our sorted map. 453 00:27:55,380 --> 00:27:58,980 So we could just continue to the next iteration of this loop. 454 00:27:59,660 --> 00:28:07,010 Otherwise, if we didn't reach the end of our sorted map, we need to go ahead and shift the lower bound 455 00:28:07,010 --> 00:28:09,620 so that way we can get the next five items. 456 00:28:09,620 --> 00:28:15,140 Because if we don't specify a lower bound, it's just going to keep grabbing the same five items over 457 00:28:15,140 --> 00:28:16,460 and over and over again. 458 00:28:16,850 --> 00:28:19,760 So we're going to set our lower bound equal to a table. 459 00:28:19,760 --> 00:28:24,470 And if you remember in the parameter section it has to be a table that has uh two keys. 460 00:28:24,470 --> 00:28:27,200 One is called key and the other one is called sort key. 461 00:28:27,470 --> 00:28:31,700 So we can do lower bound dot key. 462 00:28:31,700 --> 00:28:36,500 And we need to set this equal to the last element we got inside of our items table. 463 00:28:36,500 --> 00:28:38,120 So we could do items. 464 00:28:38,180 --> 00:28:43,490 We'll get whatever item at the last um element inside of this table. 465 00:28:43,490 --> 00:28:45,530 So that's just going to be the length of the items. 466 00:28:45,530 --> 00:28:49,610 And actually let's go ahead and head to the documentation real quick. 467 00:28:49,610 --> 00:28:54,260 And inside of the documentation, if we look at the get range async function and we look at their code 468 00:28:54,260 --> 00:29:00,770 example when they're looping through all of the items that is returned by that function, when the item 469 00:29:00,770 --> 00:29:08,540 is a table that stores the key, the sort key, as well as the value, um, for that particular item 470 00:29:08,540 --> 00:29:09,170 as well. 471 00:29:09,170 --> 00:29:12,230 So there's three keys inside of their key sort key and value. 472 00:29:12,230 --> 00:29:15,200 And that's what we need to refer to inside of our code. 473 00:29:15,560 --> 00:29:22,460 So when we're grabbing this last item inside of our items, uh, table, we can go ahead and refer to 474 00:29:22,460 --> 00:29:25,460 its key and set that as the lower bound. 475 00:29:25,460 --> 00:29:30,050 And then we can do the exact same thing for the sort key as well. 476 00:29:30,050 --> 00:29:38,630 We can just copy this, but set this equal to the last sort key inside of our items table. 477 00:29:39,320 --> 00:29:45,080 So now we should be able to properly loop through all of the different messages that are going to be 478 00:29:45,080 --> 00:29:48,740 stored inside of our map right here. 479 00:29:48,830 --> 00:29:52,790 Now you might be wondering wait a minute, there's no yield statement in here. 480 00:29:52,790 --> 00:29:53,720 What are you doing? 481 00:29:53,720 --> 00:29:58,280 And that's because technically this function does yield, so it won't crash your game. 482 00:29:58,280 --> 00:30:03,860 But considering the fact that who knows how long it's going to be before we grab our first player, 483 00:30:03,860 --> 00:30:06,440 we should actually probably put a yield statement in here. 484 00:30:06,440 --> 00:30:08,120 So we'll do the same thing of 10s. 485 00:30:08,120 --> 00:30:15,560 So that way we don't crash the game, and then we should have all the logic set up for our sort map. 486 00:30:15,560 --> 00:30:18,680 So actually let's go ahead and play test the game and try it out. 487 00:30:20,680 --> 00:30:22,480 I'll send some messages in the chat, like. 488 00:30:22,480 --> 00:30:23,440 Hello? 489 00:30:23,470 --> 00:30:25,180 Howdy. 490 00:30:25,480 --> 00:30:26,710 Uh, hi. 491 00:30:26,740 --> 00:30:28,210 What's up? 492 00:30:28,210 --> 00:30:29,740 And let's go ahead and see what prints. 493 00:30:29,740 --> 00:30:34,990 Okay, we get our map, and as you can see, it stores the different items, which are tables. 494 00:30:34,990 --> 00:30:40,420 And if we take a look at each one of those items, they have a key a sort key and the value. 495 00:30:40,420 --> 00:30:42,700 And as you can see we get hi hello. 496 00:30:42,700 --> 00:30:43,150 Howdy. 497 00:30:43,150 --> 00:30:44,290 And was up. 498 00:30:44,650 --> 00:30:52,480 And since we specified that we wanted to grab values in an ascending order, if you can tell we got 499 00:30:52,480 --> 00:30:57,550 it in in ascending order because the smallest one was high, then we're going in ascending order as 500 00:30:57,550 --> 00:30:59,140 we continue through the array. 501 00:30:59,140 --> 00:31:04,540 If we wanted to flip this around and get the longer messages first, then we would have to swap it from 502 00:31:04,540 --> 00:31:06,670 ascending to descending order. 503 00:31:07,030 --> 00:31:12,850 And if you notice down here, it's continuing to print those same messages out because they're still 504 00:31:12,850 --> 00:31:14,950 stored within our memory store. 505 00:31:14,950 --> 00:31:18,100 They're not going to be automatically removed until 100 seconds later. 506 00:31:18,100 --> 00:31:23,440 And also we did not, uh, remove them from the queue after we read them. 507 00:31:23,440 --> 00:31:27,100 So they're still stored inside of the memory store. 508 00:31:27,190 --> 00:31:32,410 Let's go ahead and wait 100 seconds and see if these values get automatically removed. 509 00:31:32,410 --> 00:31:34,120 So I'll just sit here and wait. 510 00:31:34,390 --> 00:31:35,020 All right. 511 00:31:35,020 --> 00:31:38,680 And as you can see after this printed a total of ten times. 512 00:31:38,680 --> 00:31:42,370 And since we're waiting 10s between each loop, that's 100 seconds. 513 00:31:42,370 --> 00:31:47,860 It is no longer printing out those values inside of the console, because they were automatically removed 514 00:31:47,860 --> 00:31:50,140 and cleaned up out of our memory store. 515 00:31:50,140 --> 00:31:51,910 They are gone forever. 516 00:31:52,950 --> 00:31:58,740 Let's go ahead and test out some of the other features inside of the memory store, such as, for example, 517 00:31:58,740 --> 00:32:00,540 uh, write an exclamation mark. 518 00:32:00,540 --> 00:32:01,260 Save! 519 00:32:01,590 --> 00:32:06,840 We should save this message inside of our memory store, and it should be associated with the user ID 520 00:32:06,840 --> 00:32:08,070 of our player. 521 00:32:08,400 --> 00:32:11,670 So if we go ahead and take a look and we wait here, hopefully it prints something. 522 00:32:11,670 --> 00:32:12,360 There we go. 523 00:32:12,750 --> 00:32:15,150 There is my user ID right there. 524 00:32:15,210 --> 00:32:17,850 There is the sort key which is the length of my string. 525 00:32:17,850 --> 00:32:19,290 And as you can see it's exclamation mark. 526 00:32:19,290 --> 00:32:19,830 Save. 527 00:32:19,830 --> 00:32:20,610 Very cool. 528 00:32:20,610 --> 00:32:25,530 Now let's go ahead and use that other message which was update to change that value. 529 00:32:25,530 --> 00:32:26,430 There we go. 530 00:32:26,460 --> 00:32:30,690 The previous value was save and the previous sort key was five. 531 00:32:31,230 --> 00:32:35,730 And now we should have a new value stored in place at the same key. 532 00:32:35,730 --> 00:32:36,540 There you go. 533 00:32:36,540 --> 00:32:42,660 The exact same key which is our user ID, but now it has a sort key of 100 and it's storing our new 534 00:32:42,660 --> 00:32:43,440 value. 535 00:32:43,440 --> 00:32:49,590 And of course this value also has an expiration lifetime of 100 seconds. 536 00:32:49,590 --> 00:32:54,390 So after 100 seconds this will completely disappear from our memory store. 537 00:32:54,990 --> 00:32:55,440 Okay. 538 00:32:55,440 --> 00:32:59,880 So this was likely quite a long lecture packed with a boatload of information. 539 00:32:59,880 --> 00:33:03,480 If you don't understand everything right away, that's absolutely okay. 540 00:33:03,480 --> 00:33:08,430 You can always come back to this lecture, go through different parts and rewatch the areas that you 541 00:33:08,430 --> 00:33:09,930 didn't understand. 542 00:33:09,930 --> 00:33:15,210 And I hope this lecture has given you a better understanding of data stores and how to use the API to 543 00:33:15,210 --> 00:33:16,200 interact with them. 544 00:33:16,200 --> 00:33:21,270 Before I let you go, one last thing I would like to show you is the Memory Store viewer. 545 00:33:21,270 --> 00:33:22,260 In the Creator Hub. 546 00:33:22,260 --> 00:33:28,020 You can actually view the status and how close you're getting to the limitations of memory stores for 547 00:33:28,020 --> 00:33:29,070 each of your games. 548 00:33:29,070 --> 00:33:32,340 So let's go ahead and take a look at that in the Creator Hub. 549 00:33:32,610 --> 00:33:33,240 All right. 550 00:33:33,240 --> 00:33:37,590 Here in the Creator Hub we're going to go to our game that is using memory stores. 551 00:33:37,590 --> 00:33:41,640 In this case it is my memory store uh service place. 552 00:33:41,640 --> 00:33:45,330 We can select our game and then we can go to the monitoring tab. 553 00:33:45,330 --> 00:33:49,350 And there is a section to monitor the status of your memory stores. 554 00:33:49,350 --> 00:33:56,250 So if we take a look at this and we look at the West one, our um, actually considering the fact that 555 00:33:56,250 --> 00:34:02,340 I think we were doing it through studio, it's not going to display any information in here, which 556 00:34:02,340 --> 00:34:04,530 is actually a little bit unfortunate. 557 00:34:04,650 --> 00:34:09,720 So let me actually swap to a different account that has used memory stores, so I can show you what 558 00:34:09,720 --> 00:34:11,070 these charts look like. 559 00:34:11,700 --> 00:34:15,990 Okay, so here's an example of a place that I'm currently working on where I was messing around with 560 00:34:15,990 --> 00:34:16,770 data stores. 561 00:34:16,770 --> 00:34:20,010 And this is what your charts should look like. 562 00:34:20,010 --> 00:34:25,830 It'll show you what your memory quota is based on the number of players in your game. 563 00:34:25,830 --> 00:34:30,810 So my memory quota and bytes is like around 60 something thousand. 564 00:34:30,810 --> 00:34:35,880 And down here, this blue bar will show you the memory usage that you're currently using in your data 565 00:34:35,880 --> 00:34:36,450 store. 566 00:34:36,450 --> 00:34:42,060 As you can see, I barely ever even reached the memory quota, so there's no issues there. 567 00:34:42,060 --> 00:34:48,120 If you see that your memory usage is getting very close to your memory quota, you might want to reevaluate 568 00:34:48,120 --> 00:34:52,440 how you're using your memory stores because it's going to cause you issues when you hit that quota. 569 00:34:52,830 --> 00:34:57,270 But we can go ahead and take a look at some of the other different, uh, analytics here. 570 00:34:57,270 --> 00:35:00,090 For example, the API request units. 571 00:35:00,090 --> 00:35:06,480 So this will show you how many request units I've used and my quota for my, uh, request unit. 572 00:35:06,480 --> 00:35:08,220 So I get like 2000. 573 00:35:08,220 --> 00:35:12,030 And as you can see, I'm like barely using any request units at all. 574 00:35:12,030 --> 00:35:14,190 So there's not much data to show here. 575 00:35:14,790 --> 00:35:19,170 And then if we go down here, we can see request count by API. 576 00:35:19,170 --> 00:35:23,190 So we can see like the different functions that used some different amounts. 577 00:35:23,190 --> 00:35:29,610 Like I used one request here, I used I think one right here and one right here. 578 00:35:30,630 --> 00:35:33,990 And then we can also see something called request count by status. 579 00:35:33,990 --> 00:35:41,010 It says views the breakdown of API requests uh, by response status to identify top issues. 580 00:35:41,010 --> 00:35:43,230 So there's requests per minute. 581 00:35:43,750 --> 00:35:49,060 And then I believe, oh, these are like different statuses of the different requests. 582 00:35:49,060 --> 00:35:52,600 So success, success, no items found. 583 00:35:52,900 --> 00:35:56,470 And then there's some other extra statistics in here. 584 00:35:56,470 --> 00:36:01,570 But this is basically how you can monitor your memory stores to see if there are any issues going on 585 00:36:01,570 --> 00:36:02,530 in your game. 586 00:36:03,100 --> 00:36:09,250 Alrighty, I hope you enjoyed this long, long lecture and I will see you in the next one.